package code.codeworld.common.kits;

import java.io.Serial;
import java.io.Serializable;
import java.util.function.Consumer;

/**
 * Result
 *
 * @author freecode
 * @date 2023/03/23 00:20
 */
public class Result<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    public static final int CODE_SUCCESS = 200;
    public static final int CODE_BAD = 400;
    public static final int CODE_ABSENT = 405;
    public static final int CODE_EXCEPTION = 424;
    public static final int CODE_ERROR = 500;


    private int code;

    private String msg;

    private T data;

    private Boolean finish;

    public Result() {
    }

    public Result(int code, String msg, T data, Boolean finish) {
        this.setCode(code);
        this.setMsg(msg);
        this.setData(data);
        this.setFinish(finish);
    }

    /**
     * 获取code
     *
     * @return code
     */
    public Integer getCode() {
        return this.code;
    }

    /**
     * 获取msg
     *
     * @return msg
     */
    public String getMsg() {
        return this.msg;
    }

    /**
     * 获取data
     *
     * @return data
     */
    public T getData() {
        return this.data;
    }

    /**
     * 获取finish
     *
     * @return finish
     */
    public Boolean isFinish() {
        return this.finish;
    }

    /**
     * 给code赋值，连缀风格
     *
     * @param code code
     * @return 对象自身
     */
    public Result<T> setCode(int code) {
        this.code = code;
        return this;
    }

    /**
     * 给msg赋值，连缀风格
     *
     * @param msg msg
     * @return 对象自身
     */
    public Result<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    /**
     * 给data赋值，连缀风格
     *
     * @param data data
     * @return 对象自身
     */
    public Result<T> setData(T data) {
        this.data = data;
        return this;
    }

    /**
     * 给data赋值，连缀风格
     *
     * @param finish finish
     */
    public Result<T> setFinish(Boolean finish) {
        this.finish = finish;
        return this;
    }

    // ============================  构建  ==================================

    // 构建不存在
    public static <T> Result<T> absent() {
        return new Result<>(CODE_ABSENT, "服务不存在", null, false);
    }

    // 构建成功
    public static <T> Result<T> ok() {
        return new Result<>(CODE_SUCCESS, "操作成功", null, true);
    }

    public static <T> Result<T> ok(String msg) {
        return new Result<>(CODE_SUCCESS, msg, null, true);
    }

    public static <T> Result<T> code(int code) {
        return new Result<>(code, null, null, true);
    }

    public static <T> Result<T> data(T data) {
        return new Result<>(CODE_SUCCESS, "操作成功", data, true);
    }

    // 构建失败
    public static <T> Result<T> paramError() {
        return new Result<>(CODE_BAD, "参数异常", null, false);
    }

    public static <T> Result<T> error() {
        return new Result<>(CODE_ERROR, "服务器异常", null, false);
    }

    public static <T> Result<T> error(String msg) {
        return new Result<>(CODE_ERROR, msg, null, false);
    }


    public static <T> Result<T> exception() {
        return new Result<>(CODE_EXCEPTION, "操作异常", null, false);
    }

    public static <T> Result<T> exception(String msg) {
        return new Result<>(CODE_EXCEPTION, msg, null, false);
    }

    // 构建指定状态码
    public static <T> Result<T> the(int code, String msg, T data, Boolean finish) {
        return new Result<>(code, msg, data, finish);
    }

    // try catch
    public static <T> Result<T> tryCatch(Consumer<Object> consumer, Object data) {
        try {
            consumer.accept(data);
            return ok();
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /*
     * toString()
     */
    @Override
    public String toString() {
        return "{"
                + "\"code\": " + this.getCode()
                + ", \"msg\": \"" + this.getMsg() + "\""
                + ", \"data\": \"" + this.getData() + "\""
                + "}";
    }

}
